//./node_modules/webpack/bin/webpack.js --mode=development 启动打包
const {resolve} = require('path');
const HtmlWbpackPlugin = require('html-webpack-plugin');

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//压缩css
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
//设置nodejs环境变量,默认是product，postcss-loader会读取这个参数决定怎么做css兼容
// process.env.NODE_ENV = 'development'

module.exports={
    // 单入口
    //entry:'./js/index.js',
    
    // 多入口
    //entry:['./js/index.js','./index.html'],
    entry:{
      main: './js/index.js',
      test: './js/test.js'
    },
    output:{
        filename: 'js/[name].[contenthash:10].js',
        path: resolve(__dirname, 'dist')
    },
    //module就是用来配置loader的地方
    module:{
        //不同文件必须配置不同的loader
        rules:[
            /*
            语法检查： eslint-loader eslint
            注意：只检查自己的代码，不查第三方代码，通过exclude排除
            npm i eslint-loader eslint -D
            */
            {
                test:/\.js$/,
                exclude: /node_modules/,
                //单个loader的写法可以不用嵌套在use里
                loader: 'eslint-loader',
                //优先执行
                enforce: 'pre',
                options:{}
            },
            /*
            npm install -D babel-loader @babel/core @babel/preset-env
            js兼容处理，ES6语法-->ES5及以下语法等
            问题：只能转换基本语法，比如promise等高级语法是不能转换的。使用npm install -D @babel/polyfill,在js代码里加入import '@babel/polyfill'
            但增大代码体积。所以，也可以使用core-js来做按需转换。
            */
            {
                test:/\.js$/,
                exclude: /node_modules/,
                //多个loader的话用use数组，并且如果loader没有配置，可以值接写名字并省略loader关键字，如thread-loader如果有其他配置要写对象形式如babel-loader
                use: [
                  /*开启多进程打包
                    进程启动大概600ms，进程通讯也要开销，所以只有工作消耗时间比较长，才需要进程打包
                  */
                  'thread-loader',
                  {
                  loader: 'babel-loader',
                  options: {
                    presets: [
                      ['@babel/preset-env', { targets: "defaults" }]
                    ],
                    //需要在打包js css文件使用hash值，让在修改后改变hash值，使其在浏览器缓存失效
                    cacheDirectory:true
                  }
              }
            ]},
            /*
            处理css
            */
            {
                test: /\.css$/,
                use: [
                    // npm i style-loader css-loader -D
                    //创建style标签，将样式放入,所以不会有输出，如果需要输出用minicss来打包
                    //'style-loader',
                    //mimicss loader替代style-loader，将提取js中的css成单独文件
                    {
                        loader: MiniCssExtractPlugin.loader,
                        //不做这个设置找不到图片，会使用/img/xxx.jpeg路径，但实际是../img/xxx.jpeg路径
                        options:{
                            publicPath: '../'
                        }
                    },
                    //将css文件整合到js文件中
                    'css-loader',
                    /*
                    css兼容处理：postcss-loader postcss-preset-env
                    npm install --save-dev postcss-loader postcss postcss-preset-env
                    postcss-preset-env帮postcss从package.json中的browserlist的配置，通过配置加载指定css兼容样式。
                    */
                    {
                        loader: 'postcss-loader',
                        options: {
                          postcssOptions: {
                            plugins: [
                              [
                                'postcss-preset-env',
                                {
                                  // 其他选项
                                },
                              ],
                            ],
                          },
                        },
                    }
                ]
                
            },
            {
                test:/\.less$/,
                use: [
                    // npm i style-loader css-loader less-loader -D
                    'style-loader',
                    // {
                    //     loader: MiniCssExtractPlugin.loader,
                    //     //不做这个设置找不到图片，会使用/img/xxx.jpeg路径，但实际是../img/xxx.jpeg路径
                    //     options:{
                    //         publicPath: '../'
                    //     }
                    // },
                    'css-loader',
                    //将less文件编译成css文件
                    /*
                    css兼容处理：postcss-loader postcss-preset-env
                    npm install --save-dev postcss-loader postcss postcss-preset-env
                    postcss-preset-env帮postcss从package.json中的browserlist的配置，通过配置加载指定css兼容样式。
                    */
                    {
                        loader: 'postcss-loader',
                        options: {
                          postcssOptions: {
                            plugins: [
                              [
                                'postcss-preset-env',
                                {
                                  // 其他选项
                                },
                              ],
                            ],
                          },
                        },
                    },
                    'less-loader'
                ]
            },
            {
                // npm i url-loader file-loader -D
                // 默认处理不了html种的img标签，用来处理url函数
                test:/\.jpeg$/,
                loader: 'url-loader',
                options:{
                    limit:8 *1024,
                    esModule: false,
                    outputPath: 'img'
                }
            },
            {
                test:/\.html$/,
                //处理html文件img图片，使用的commonjs引入。
                loader: 'html-loader', 
                options:{
                    esModule: false,
                }
            }

        ]
    },
    plugins:[
        //默认创建一个空的index.html并引入main.js
        new HtmlWbpackPlugin({
            //复制指定的html文件，并自动引入打包的js
            template: './index.html',
            //压缩html
            minify:{
                collapseWhitespace:false,//移除空格
                removeComments:false//移除注释
            }
        }),
        new MiniCssExtractPlugin({
            filename:'css/index[contenthash:10].css'
        })
    ],
    //production会自动压缩JS代码
    mode:'development',
    // dev server编译，启动开发服务器，自动刷新修改内容让浏览器实时显示，但不会有输出打包结果 ，所有的数据都是在内存中。所以需要打包结果的时候还是需要运行webpack
    // npm i webpack-dev-server -D
    //webpack-dev-server: npx webpack serve来启动
    devServer:{
        //运行代码的目录
        contentBase: resolve(__dirname, 'build'),
        //监视contentBase目录下所有文件，一旦变化重新reload
        watchContentBase: true,
        watchOptions:{
          //忽略监视文件
          ignore: /node_modules/
        },
        //启动gzip压缩
        compress: true,
        port: 8080,
        /*
        HMR: hot module replacement 热模块替换，一个模块发生变化，只重新打包变化模块，提升构建速度
        css（style-loader处理的）,js（默认没有HMR功能）,html（默认没有HMR功能）
        */
        hot:true,
        host: 'localhost',
        progress: true, //显示打包的进度
        
    },
    /*
    source-map:提供源代码和构建后代码的映射技术
    [inline-][hidden-][eval-][nosources-][cheap-[module-]]source-map
    source-map：外部生成xxx.js.map,错误代码提示准确，能定位到源代码位置
    inline-source-map：内联到生成js文件里，错误代码提示准确，能定位到源代码位置
    hidden-source-map：外部生成独立的xxx.js.map，但是没有源代码的错误位置只能提示构建后代码错误位置
    */
    devtool: 'source-map',
    optimization:{
      /*将node_modules中的代码单独打包一个chunk最终输出
        并分析多入扣chunk中，有没有公共的文件（公共文件大小需要达到一定的大小）。如果有会打包成单独的一个chunk
      */
      splitChunks:{
        chunks: 'all'
      },
      minimizer: [
        // For webpack@5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
        // `...`,
        new CssMinimizerPlugin(),
      ],
      //需要压缩css的时候选择true
      minimize: false,
    },
    externals:{
      //需要忽略打包的模块，比如jquery
      //jquery:'jQuery'
    }
}